1.注册事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
btns[0].onclick = function() { alert('hi'); } btns[0].onclick = function() { alert('hao a u'); }
btns[1].addEventListener('click', function() { alert(22); }) btns[1].addEventListener('click', function() { alert(33); })
btns[2].attachEvent('onclick', function() { alert(11); })
|
2.删除事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| divs[0].onclick = function () { alert(11); divs[0].onclick = null; }
divs[1].addEventListener('click', fn) function fn() { alert(22); divs[1].removeEventListener('click', fn); }
divs[2].attachEvent('onclick', fn1);
function fn1() { alert(33); divs[2].detachEvent('onclick', fn1); }
|
3.DOM事件流
事件流描述的是从页面中接收事件的顺序。 事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即 DOM 事件流。 比如我们给一个div 注册了点击事件:
DOM 事件流分为3个阶段:
- 捕获阶段:网景最早提出,由 DOM 最顶层节点开始,然后逐级向下传播到到最具体的元素接收的过程。
- 当前目标阶段
- 冒泡阶段:IE 最早提出,事件开始时由最具体的元素接收,然后逐级向上传播到到 DOM 最顶层节点的过程。
注意
- JS 代码中只能执行捕获或者冒泡其中的一个阶段。
- onclick 和 attachEvent 只能得到冒泡阶段。
- addEventListener(type, listener[, useCapture])第三个参数如果是 true,表示在事件捕 获阶段调用事件处理程序;如果是 false(不写默认就是false),表示在事件冒泡阶段调用事件处理 程序。
- 实际开发中我们很少使用事件捕获,我们更关注事件冒泡。
- 有些事件是没有冒泡的,比如 onblur、onfocus、onmouseenter、onmouseleave
- 事件冒泡有时候会带来麻烦,有时候又会帮助很巧妙的做某些事件。
4.事件对象
(1)定义
event,它有很多属性和方法。
- 事件对象我们可以自己命名 比如 event 、 evt、 e
1 2 3 4 5 6 7 8 9
|
eventTarget.onclick = function(event) { console.log(event); } eventTarget.addEventListener('click', function(event) { console.log(event); }
|
(2)e.target 和 this 的区别
- this 是事件绑定的元素, 这个函数的调用者(绑定这个事件的元素) ;有一个跟 this 有个非常相似的属性 currentTarget 但是ie678不认识
- e.target 是事件触发的元素。
(3)阻止默认行为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| var a = document.querySelector('a'); a.addEventListener('click', function(e) { e.preventDefault(); })
a.onclick = function(e) {
return false; alert(11); }
|
5.阻止事件冒泡
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
var son = document.querySelector('.son'); son.addEventListener('click', function (e) { alert('son'); e.stopPropagation(); }, false); var father = document.querySelector('.father'); father.addEventListener('click', function () { alert('father'); }, false); document.addEventListener('click', function () { alert('document'); })
|
6.事件委托(代理、委派)
事件冒泡本身的特性,会带来的坏处,也会带来的好处,需要我们灵活掌握。程序中也有如此场景:
1 2 3 4 5 6 7
| <ul> <li>知否知否,应该有弹框在手</li> <li>知否知否,应该有弹框在手</li> <li>知否知否,应该有弹框在手</li> <li>知否知否,应该有弹框在手</li> <li>知否知否,应该有弹框在手</li> </ul>
|
点击每个 li 都会弹出对话框,以前需要给每个 li 注册事件,是非常辛苦的,而且访问 DOM 的次数越多,这就会延长整个页面的交互就绪时间。
事件委托也称为事件代理, 在 jQuery 里面称为事件委派。
事件委托的原理:不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点。(面试考点)
以上案例:给 ul 注册点击事件,然后利用事件对象的 target 来找到当前点击的 li,因为点击 li,事件会冒泡到 ul 上, ul 有注册事件,就会触发事件监听器。
1 2 3 4 5 6 7
| var ul = document.querySelector('ul'); ul.addEventListener('click', function(e) { e.target.style.backgroundColor = 'pink'; })
|
事件委托的作用:只操作了一次 DOM ,提高了程序的性能。
7.鼠标事件:禁止右键菜单和选择
1 2 3 4 5 6 7 8 9 10 11 12 13
| <body> 我是一段不愿意分享的文字 <script> document.addEventListener('contextmenu', function(e) { e.preventDefault(); }) document.addEventListener('selectstart', function(e) { e.preventDefault(); }) </script> </body>
|
8.鼠标事件对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| document.addEventListener('click', function(e) { console.log(e.clientX); console.log(e.clientY); console.log('---------------------'); console.log(e.pageX); console.log(e.pageY); console.log('---------------------'); console.log(e.screenX); console.log(e.screenY); })
|
案例:跟随鼠标的天使
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> img { position: absolute; top: 2px; } </style> </head>
<body> <img src="images/angel.gif" alt=""> <script> var pic = document.querySelector('img'); document.addEventListener('mousemove', function(e) { var x = e.pageX; var y = e.pageY; console.log('x坐标是' + x, 'y坐标是' + y); pic.style.left = x - 50 + 'px'; pic.style.top = y - 40 + 'px'; }); </script> </body>
|
9.键盘事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| document.onkeyup = function () { console.log('我弹起了'); }
document.addEventListener('keyup', function () { console.log('我弹起了'); })
document.addEventListener('keypress', function () { console.log('我按下了press'); })
document.addEventListener('keydown', function () { console.log('我按下了down'); })
|
keycode属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
document.addEventListener('keyup', function(e) { console.log('up:' + e.keyCode); if (e.keyCode === 65) { alert('您按下的a键'); } else { alert('您没有按下a键') } }) document.addEventListener('keypress', function(e) { console.log('press:' + e.keyCode); })
|
案例:模拟京东按键聚焦到输入框
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <body> <input type="text"> <script> var search = document.querySelector('input'); document.addEventListener('keyup', function(e) { if (e.keyCode === 83) { search.focus(); } }) </script> </body>
|
案例:模拟输入框文字放大效果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <style> * { margin: 0; padding: 0; }
.search { position: relative; width: 178px; margin: 100px; }
.con { position: absolute; top: -40px; width: 171px; border: 1px solid rgba(0, 0, 0, .2); box-shadow: 0 2px 4px rgba(0, 0, 0, .2); padding: 5px 0; font-size: 18px; line-height: 20px; color: #333; }
.con::before { content: ''; width: 0; height: 0; position: absolute; top: 28px; left: 18px; border: 8px solid #000; border-style: solid dashed dashed; border-color: #fff transparent transparent; } </style> </head>
<body> <div class="search"> <div class="con">123</div> <input type="text" placeholder="请输入您的快递单号" class="jd"> </div> <script> var con = document.querySelector('.con'); var jd_input = document.querySelector('.jd'); jd_input.addEventListener('keyup', function () { if (this.value == '') { con.style.display = 'none'; } else { con.style.display = 'block'; con.innerText = this.value; } }) jd_input.addEventListener('blur', function () { con.style.display = 'none'; }) jd_input.addEventListener('focus', function () { if (this.value !== '') { con.style.display = 'block'; } }) </script> </body>
|